package com.ys.service.hr.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.dto.AddDto;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.TwlStock;
import com.ys.entity.hr.TwlStockIn;
import com.ys.entity.hr.TwlStockInDetail;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.enume.hr.TwlStockChangeEnum;
import com.ys.mapper.hr.HrMapper;
import com.ys.mapper.hr.TwlStockInDetailMapper;
import com.ys.mapper.hr.TwlStockInMapper;
import com.ys.mapper.hr.TwlStockMapper;
import com.ys.service.flow.YspTaskService;
import com.ys.service.hr.TwlStockInService;
import com.ys.service.hr.TwlStockService;
import com.ys.util.DateUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("twlStockInService")
public class TwlStockInServiceImpl implements TwlStockInService {

	@Autowired
	private HrMapper hrMapper;
	@Autowired
	private TwlStockMapper twlStockMapper;
	@Autowired
	private TwlStockInMapper twlStockInMapper;
	@Autowired
	private TwlStockInDetailMapper twlStockInDetailMapper;

	@Autowired
	private TwlStockService twlStockService;
	@Autowired
	private YspTaskService yspTaskService;
	/**
	 * 新增
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@Override
	public R add(String bid, String companyVid, String orgid, String remarkStockIn, String detailArr, Long menuId) throws Exception {

		if (bid == null || bid.length() == 0) {
			return R.error("单号不能为空");
		} else if(new TwlStockIn().setBid(bid).count() > 0) {
			return R.error("单号已存在");
		}
		
		if (companyVid == null || companyVid.length() == 0) {
			return R.error("公司编码不能为空");
		}
		
		if (orgid == null || orgid.length() == 0) {
			return R.error("部门编码不能为空");
		}
		
		/*
		 *  验证详情数据物料
		 *  1、编码不能为空
		 *  2、数量不能为空
		 *  3、价格不能为空
		 */
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			String materialCode = detailJO.getString("materialCode");
			if (materialCode == null || materialCode.length() == 0) {
				return R.error("物料编码不能为空");
			}

			Integer num = detailJO.getInteger("num");
			if (num == null) {
				return R.error("数量不能为空");
			} else if (num <= 0) {
				return R.error("数量必须为正");
			}
			BigDecimal price = detailJO.getBigDecimal("price");
			if (price == null) {
				return R.error("价格不能为空");
			} else if (price.compareTo(BigDecimal.ZERO) < 0) {
				return R.error("价格必须为正");
			}
		}
		
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();
		
		TwlStockIn entity = null;
		{
			Integer effectStock = FlowEnum.EffectStock.NOT_EFFECT.value;
			Long createChangeId = tsUserChange.getId();
			String remark = remarkStockIn;
			entity = TwlStockIn.twlStockIn(bid, effectStock, createChangeId, remark, companyVid, orgid, 1);
			twlStockInMapper.insert(entity);
		}
		
		// 添加物料入库明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			
			String bidStockIn = bid;
			String materialCode = detailJO.getString("materialCode");
			Integer num = detailJO.getInteger("num");
			BigDecimal price = detailJO.getBigDecimal("price");
			String img = detailJO.getString("img");
			String remark = detailJO.getString("remark");
			TwlStockInDetail twlStockInDetail = TwlStockInDetail.twlStockInDetail(bidStockIn, materialCode, num, price, img, remark, 1);
			twlStockInDetailMapper.insert(twlStockInDetail);
		}
		
		/*
		 * 流程初始化
		 */
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, bid, createUserId);
		}
		return R.ok(AddDto.closeAndReload());
	}
	
	@Override
	@Transactional
	public R edit(String bid, String companyVid, String orgid, String remarkStockIn, String detailArr, Long menuId) throws Exception {
		
		Integer stateFlow = yspTaskService.flowState(bid);
		if (stateFlow != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("非制单中数据，无法修改");
		}
		
		// 验证是否制单人
		YsProcInst entity = new YsProcInst().setBid(bid).queryFirst();
		if (!entity.getCreateUserId().equals(ShiroUtils.getUserId())) {
			return R.error("非制单人无法修改");
		}
		
		/*
		 *  验证详情数据物料
		 *  1、编码不能为空
		 *  2、数量不能为空
		 *  3、价格不能为空
		 */
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			String materialCode = detailJO.getString("materialCode");
			if (materialCode == null || materialCode.length() == 0) {
				return R.error("物料编码不能为空");
			}

			Integer num = detailJO.getInteger("num");
			if (num == null) {
				return R.error("数量不能为空");
			} else if (num <= 0) {
				return R.error("数量必须为正");
			}
			BigDecimal price = detailJO.getBigDecimal("price");
			if (price == null) {
				return R.error("价格不能为空");
			} else if (price.compareTo(BigDecimal.ZERO) < 0) {
				return R.error("价格必须为正");
			}
		}
		
		// 删除旧的详情数据
		hrMapper.deleteBatchTwlStockInDetailByBid(bid);
		
		// 添加物料入库明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			
			String bidStockIn = bid;
			String materialCode = detailJO.getString("materialCode");
			Integer num = detailJO.getInteger("num");
			BigDecimal price = detailJO.getBigDecimal("price");
			String img = detailJO.getString("img");
			String remark = detailJO.getString("remark");
			TwlStockInDetail twlStockInDetail = TwlStockInDetail.twlStockInDetail(bidStockIn, materialCode, num, price, img, remark, 1);
			twlStockInDetailMapper.insert(twlStockInDetail);
		}
		
		return R.ok(AddDto.gotoEdit("/web/hr/twlStockIn/toFlow?bid=" + bid));
	}

	@Override
	@Transactional
	public R deleteTrue(Long id) throws Exception {
		if (id == null) {
			return R.error("ID不能为空");
		}
		
		TwlStockIn entity = new TwlStockIn().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		
		if (!tsUserChange.getUserId().equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		
		// 删除主数据
		twlStockInMapper.deleteTrue(id);
		
		// 删除子数据
		List<TwlStockInDetail> listDetail = new TwlStockInDetail().setBidStockIn(entity.getBid()).queryList();
		for(TwlStockInDetail detail : listDetail) {
			twlStockInDetailMapper.deleteTrue(detail.getId());
		}
		
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	@Override
	@Transactional
	public R flowPass(String bid, String loginUserId) throws Exception {
		
		try {
			Flow f = yspTaskService.flowPass(bid, loginUserId);
			if (f.getCode() == Flow.Code.FAILED.value) {
				return R.error(f.getMsg());
			} else {
				
				if (f.getState() == Flow.State.FINISH.value) {
					flowFinish(bid);
				}
				return R.ok();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return R.error("服务器正在开小差，请联系客服");
		}
	}

	@Override
	public R flowRefuse(String bid, String reason, String loginUserId) throws Exception {
		
		R r = yspTaskService.flowRefuse(bid, reason, loginUserId);
		return r;
	}

	@Override
	@Transactional
	public void flowFinish(String bid) throws Exception {

		TwlStockIn entity = new TwlStockIn().setBid(bid).queryFirst();
		
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		twlStockInMapper.update(entity);
		
		List<TwlStockInDetail> listDetail = new TwlStockInDetail().setBidStockIn(bid).queryList();
		for (int i = 0; i < listDetail.size(); i++) {
			TwlStockInDetail detail = listDetail.get(i);
			// 添加物料库存
			TwlStock twlStock = null;
			{
				String companyVid = entity.getCompanyVid();
				String orgid = entity.getOrgid();
				String materialCode = detail.getMaterialCode();
				Integer num = detail.getNum();
				Integer numAll = detail.getNum();
				Integer numFrozen = 0;
				BigDecimal price = detail.getPrice();
				String remark = detail.getRemark();
				Long stockInDetailId = detail.getId();
				String stockInDay = DateUtil.getYYMMDD(new Date());
				twlStock = TwlStock.twlStock(companyVid, orgid, materialCode, num, numAll, numFrozen, price, stockInDetailId, stockInDay, remark, 1);
				twlStockMapper.insert(twlStock);
			}
			
			// 添加变动记录及流水记录
			Long stockId = twlStock.getId();
			Integer type = TwlStockChangeEnum.Type.IN.value;
			Long sourceId = detail.getId();
			String sourceBid = bid;
			Integer sourceNum = detail.getNum();
			twlStockService.change(stockId, type, sourceId, sourceBid, sourceNum);
		}
	}

	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList(String bid) throws Exception{
		List<Map<String, Object>> sonlist = new TwlStockInDetail()
				.setBidStockIn(bid)
				.addLeftJoin("TWL_StockIn B on B.Bid = A.BidStockIn")
				.setFields("")
				.addField("A.Num num")
				.addField("A.Price price")

				.addLeftJoin("TB_Material C on C.Code = A.MaterialCode")
				.addField("C.Name materialName")
				.addField("C.Remark materialRemark")
				.queryMap();
		return sonlist;
	}


}
